package cn.myfirefly.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 对象操作类
 * @author zhouxiaoming
 */
public class ObjectUtil {
	private static Logger logger = LoggerFactory.getLogger(ObjectUtil.class);
	
	/**
	 * 通过反射进行对象拷贝，获取一个新的对象。
	 * 支持父类的属性
	 * @param object
	 * @return
	 * @throws Exception
	 */
	public static Object objectCopy(Object object) {
		Object objectCopy = null;
		try {
			Class<?> classType = object.getClass();
			objectCopy = classType.getConstructor(new Class[] {}).newInstance(new Object[] {});
			// 获得对象的所有成员变量
			List<Field> fieldList = getAllFields(classType);
			for (Field field : fieldList) {
				// 获取成员变量的名字
				String name = field.getName();
				// 获取get和set方法的名字
				String firstLetter = name.substring(0, 1).toUpperCase();
				String getMethodName = "get" + firstLetter + name.substring(1);
				String setMethodName = "set" + firstLetter + name.substring(1);
				// 获取方法对象
				Method getMethod = classType.getMethod(getMethodName, new Class[] {});
				Method setMethod = classType.getMethod(setMethodName, new Class[] { field.getType() });
				// 调用get方法获取旧的对象的值
				Object value = getMethod.invoke(object, new Object[] {});
				// 调用set方法将这个值复制到新的对象中去
				setMethod.invoke(objectCopy, new Object[] { value });
				
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return objectCopy;
	}

	public static Object getFieldValue(Object object, String fieldName) throws Exception {
		Object value = null;
		Class<?> classType = object.getClass();
		// 获得对象的所有成员变量
		Field[] fields = classType.getDeclaredFields();
		for (Field field : fields) {
			// 获取成员变量的名字
			String name = field.getName();
			if (StrUtil.equals(fieldName, name)) {
				String firstLetter = name.substring(0, 1).toUpperCase();
				String getMethodName = "get" + firstLetter + name.substring(1);
				// 获取方法对象
				Method getMethod = classType.getMethod(getMethodName, new Class[] {});
				// 调用get方法获取对象的值
				value = getMethod.invoke(object, new Object[] {});
				break;
			}
		}

		return value;
	}

	private static List<Field> getAllFields(Class<?> modelClass) {
		List<Field> fieldList = new ArrayList<>();
		Class<?> tempClass = modelClass;
		while (tempClass != null && !tempClass.getName().toLowerCase().equals("java.lang.object")) {
			fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
			tempClass = tempClass.getSuperclass();
		}
		return fieldList;
	}
}
